package center

import (
	"base"
	"emma/uuid"
	"encoding/json"
	"game_server/logic/gate/api"
	. "game_server/logic/internal"
	"game_server/logic/player/api"
	"leaf/gate"
	"proto/server/center"
	"proto/server/game"
)

type centerService struct {
}

func init() {
	service := new(centerService)
	Protocol.Register(new(proto_server_center.OnRegister), service.onRegister)
	Protocol.Register(new(proto_server_game.Login), service.login)
	Protocol.Register(new(proto_server_game.OnGateClose), service.onGateClose)
	Protocol.Register(new(proto_server_game.OnGateRegister), service.onGateRegister)
}

func (*centerService) onRegister(args []interface{}) {
	msg := args[0].(*proto_server_center.OnRegister)
	agent := args[1].(gate.Agent)
	if !verifyAgent(agent) {
		return
	}

	system.gameAgentId = base.AgentId(msg.AgentId)
	uuid.SetRandId(int(system.gameAgentId))

	addrs := make(map[base.AgentId]string)
	if err := json.Unmarshal(msg.Data, &addrs); err == nil {
		for agentId, address := range addrs {
			gate_api.Dial(agentId, address)
		}
	} else {
		base.Logger.Error("FIXME")
	}
}

func (*centerService) login(args []interface{}) {
	msg := args[0].(*proto_server_game.Login)
	base.Logger.Debug("player login, msg: %s", msg)

	agent := args[1].(gate.Agent)
	if !verifyAgent(agent) {
		return
	}

	playerId := base.PlayerId(msg.PlayerId)
	loginTimestamp := msg.Timestamp
	gateId := base.AgentId(msg.GateId)
	player_api.Login(playerId, loginTimestamp, gateId)
}

func (*centerService) onGateClose(args []interface{}) {
	msg := args[0].(*proto_server_game.OnGateClose)
	base.Logger.Debug("on gate close, msg: %s", msg)

	agent := args[1].(gate.Agent)
	if !verifyAgent(agent) {
		return
	}

	agentId := base.AgentId(msg.AgentId)
	gate_api.Close(agentId)
}

func (*centerService) onGateRegister(args []interface{}) {
	msg := args[0].(*proto_server_game.OnGateRegister)
	base.Logger.Debug("on gate register, msg: %s", msg)

	agent := args[1].(gate.Agent)
	if !verifyAgent(agent) {
		return
	}

	agentId := base.AgentId(msg.AgentId)
	address := msg.Addr
	gate_api.Dial(agentId, address)
}

func verifyAgent(agent gate.Agent) (result bool) {
	result = (agent == system.agent)
	if !result {
		base.Logger.Error("invalid center server agent")
	}

	return
}
